/**$Licence:
 *  Copyright (C) 2008 - 2012 www.java1995.com . All rights reserved.
 *
 *  Use this however/wherever you like, just don't blame me if it breaks anything.
 *
 */

package com.blazemina.container;

import java.util.concurrent.locks.ReadWriteLock;

import com.blazegame.logging.Logger;
import com.blazegame.logging.LoggerFactory;
import com.blazemina.command.Command;
import com.blazemina.command.CommandFactory;
import com.blazemina.command.DefaultJavaCommandFactory;
import com.blazemina.config.BlazeminaConfig;
import com.blazemina.config.ConfigInitializeException;
import com.blazemina.mina.Request;
import com.blazemina.mina.Response;
import com.blazemina.util.ClassUtils;

/**
 * @author JackChu
 * @version 1.0.0 2012-1-12 下午8:18:38
 */
public class DefaultRequestProcessor extends GenericRequestProcessor {

	protected CommandFactory commandFactory;

	private ReadWriteLock lock = new java.util.concurrent.locks.ReentrantReadWriteLock();
	
	private final static Logger log = LoggerFactory.getLogger(DefaultJavaCommandFactory.class);

	@Override
	public final void processor(Request request, Response response) {
		Command command = processCommandCreate(request);
		command.execute(request, response);
	}

	/**
	 * 创建对应的Command
	 * 
	 * @param request
	 * @param blazeminaConfig
	 * @return
	 */
	protected Command processCommandCreate(Request request) {
		String command = request.getMessage().getCommand();
		commandFactory = processCommandFactoryCreate();
		return (Command) commandFactory.lookup(command);
	}

	/**
	 * 使用Java反射创建CommandFactory,如果使用别的方式创建，可以覆盖此方法
	 * 
	 * @param blazeminaConfig
	 * @return
	 */
	protected CommandFactory processCommandFactoryCreate() {
		BlazeminaConfig blazeminaConfig = getBlazeminaConfig();
		lock.readLock().lock();
		try {
			if (commandFactory != null) {
				return commandFactory;
			}
		} finally {
			lock.readLock().unlock();
		}
		lock.writeLock().lock();
		try {
			String commandFactory0 = blazeminaConfig.getProtocols()
					.getCommandFactory();
			commandFactory = (CommandFactory) ClassUtils
					.applicationInstance(commandFactory0);
		} catch (Exception e) {
			log.error("create commandFactory error", e);
			throw new ConfigInitializeException("create command factory error"+
					e);
		} finally {
			lock.writeLock().unlock();
		}
		return commandFactory;
	}

}
